﻿using CIS.Common.Dtos.ClientDtos;
using CIS.Common.Dtos.CommandDtos;
using CIS.Common.Entitys;
using CIS.Common.Enums;
using CIS.Common.Grpc;
using CIS.Server.Common.Responses;
using CIS.Server.Manager.Equipment;
using CIS.Server.Manager.Job;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Net;

namespace CIS.Server.Controllers
{
    [Route("[controller]/[action]")]
    [ApiController]
    public class PortController : ControllerBase
    {
        private readonly IEquipmentManager _equipmentManager;
        private readonly IJobManager _jobManager;

        public PortController(IEquipmentManager equipmentManager,IJobManager jobManager)
        {
            _equipmentManager = equipmentManager;
            this._jobManager = jobManager;
        }

        [HttpGet]
        public async Task<ResponseResult> GetPorts()
        {
            ResponseResult response = new ResponseResult();
            try
            {
                List<PortEntity> ports = await _equipmentManager.GetAllPortsAsync();
                if(ports !=null &&  ports.Count > 0)
                {
                    ports = ports.OrderBy(p => p.PortId).ToList();
                    response.IsSuccess = true;
                    response.StatusCode = HttpStatusCode.OK;
                    response.Message = "Operation Is Success";
                    response.Data = ports;
                }
                else
                {
                    response.IsSuccess = false;
                    response.StatusCode = HttpStatusCode.OK;
                    response.Message = "Operation Is Failed Because Can't Find Any Port";
                }
                return response;
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.StatusCode = HttpStatusCode.InternalServerError;
                response.Message = "Operation Is Failed Because Server Is Error";
                return response;
            }
        }

        [HttpPost]
        public async Task<ResponseResult> SendPortControlCommand([FromBody] string parameter)
        {
            ResponseResult response = new ResponseResult();
            var para = JsonConvert.DeserializeObject<PortControlCommandDto>(parameter);
            string controlType = Enum.GetName(typeof(PortControlType),para.PortControlCommand);
            switch (controlType)
            {
                case "UnClamp":
                    response.IsSuccess = true;
                    response.StatusCode = HttpStatusCode.OK;
                    response.Message = "Port UnClamp Operation Is Success";
                    response.Data=await _equipmentManager.SendPortCommand(para.SourceId, para);
                    break;
                case "Clamp":
                    response.IsSuccess = true;
                    response.StatusCode = HttpStatusCode.OK;
                    response.Data =await _equipmentManager.SendPortCommand(para.SourceId, para);
                    response.Message = "Port Clamp Operation Is Success";
                    break;
            }
            return response;
        }

        [HttpPost]
        public async Task<ResponseResult> SendCassetteMapDownLoadCommand([FromBody] string parameter)
        {
            ResponseResult response = new ResponseResult();
            try
            {
                CassetteMapDownLoadClientDto? dto = JsonConvert.DeserializeObject<CassetteMapDownLoadClientDto>(parameter);
                PortEntity port = await _equipmentManager.GetPortByPortIdAsync(dto?.PortId);
                var jobs = await _jobManager.GetJobsByPortIdAsync(dto?.PortId);
                if (dto != null && dto.JobInfos.Count > 0)
                {
                    List<JobEntity> updateJobs = new List<JobEntity>();
                    List<JobEntity> AddJobs = new List<JobEntity>();
                    foreach (var item in dto.JobInfos)
                    {
                        var job = jobs.Find(j => j.JobId == item.JobId);
                        if (job != null && item != null)
                        {
                            job.PPID = item.PPID;
                            job.Judge = item.Judge;
                            job.Grade = item.Grade;
                            job.Status = item.Status;
                            job.ProductType = item.ProductType;
                            job.SlotState = item.SlotState;
                            job.Thickness = item.Thickness;
                            job.WorkOrder = item.WorkOrder;
                            updateJobs.Add(job);
                        }
                        else
                        {
                            JobEntity jobEntity = new JobEntity();
                            jobEntity.InPutPortId = port.PortId;
                            jobEntity.LotId = item.LotId;
                            jobEntity.ProductSize = item.ProductSize;
                            jobEntity.JobId = item.JobId;
                            jobEntity.GlassType = item.GlassType.ToString();
                            jobEntity.CassetteSequenceNo = item.CassetteSequenceNo;
                            jobEntity.SlotSequenceNo = item.SlotSequenceNo;
                            jobEntity.GlassCode = item.GlassCode;
                            jobEntity.ProductCategory = item.ProductCategory;
                            jobEntity.ProductCategory = item.ProductCategory;
                            jobEntity.Judge = item.Judge;
                            jobEntity.PPID = item.PPID;
                            jobEntity.Grade = item.Grade;
                            jobEntity.Status = item.Status;
                            jobEntity.ProductType = item.ProductType;
                            jobEntity.SlotState = item.SlotState;
                            jobEntity.Thickness = item.Thickness;
                            jobEntity.WorkOrder = item.WorkOrder;
                            AddJobs.Add(jobEntity);
                        }
                    }
                    if (updateJobs.Count > 0)
                    {
                        await _jobManager.UpdateManyJobsAsync(updateJobs);
                    }
                    if (AddJobs.Count > 0)
                    {
                        await _jobManager.AddManyJobsAsync(AddJobs);
                    }
                    port.PPID = dto.PPID;
                    port.LotId = dto.LotId;
                    port.PortProductType = dto.ProductType;
                    await _equipmentManager.UpdatePortAsync(port);
                    response.IsSuccess = true;
                    response.StatusCode = HttpStatusCode.OK;
                    response.Message = "Operation Is Success";
                    response.Data = dto;
                }
                else
                {
                    response.IsSuccess = false;
                    response.StatusCode = HttpStatusCode.OK;
                    response.Message = "Operation Is Failed Because Can't Find Any Port";
                }
                return response;
            }
            catch (Exception ex)
            {
                response.IsSuccess = false;
                response.StatusCode = HttpStatusCode.InternalServerError;
                response.Message = "Operation Is Failed Because Server Is Error";
                return response;
            }
        }

    }
}
